package Server;

import java.io.*;
import java.net.Socket;
import java.util.Objects;

import Data.*;
import DataControl.ClientDataResolver;
import DataControl.ServerDataSender;

public class ClientHandler implements Runnable {
    private Socket clientSocket; // 客户端套接字
    private ObjectInputStream inputStream;// 当前输入流
    private ClientDataResolver clientDataResolver=new ClientDataResolver("F:/");// 客户端数据解析器

    private ClinetData clientData=new ClinetData();// 客户端命令数据
    private DoCommend doCommend=new DoCommend();// 命令执行器

    /**
     * 构造方法：构造处理连接类
     * @param clientSocket 客户端连接套接字
     * @throws IOException
     */
    public ClientHandler(Socket clientSocket) throws IOException {
        this.clientSocket = clientSocket;
        System.out.println("客户端已连接");

    }

    /**
     * 实现Runnable接口的run方法,用于处理客户端发送的任务
     */
    @Override
    public void run() {
        while (true) {
            //重置命令
            clientData=new ClinetData();
            // 获取客户端发送的数据
            getClientData();
            // 客户端数据解析类分析数据，获取命令以及可能的参数
            this.clientData=clientDataResolver.dealData(clientData);
            //根据客户端命令执行操作
            doCommend.DoCommend(this.clientData,this.clientSocket);
        }
    }

    /**
     * 获取客户端发送的数据
     */
    private void getClientData() {
        /**
         * 处理数据反序列化的时候，读取的类位置为客户端的地址。
         */
        class CustomObjectInputStream extends ObjectInputStream {
            public CustomObjectInputStream(InputStream in) throws IOException {
                super(in);
            }

            @Override
            protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
                // 直接返回服务器端的 Data.ClinetData 类
                if ("Client.Data.ClinetData".equals(desc.getName())) {
                    return Data.ClinetData.class;
                }
                // 对于其他类，使用默认的类加载器
                return super.resolveClass(desc);
            }
        }
        try{
            System.out.println("获取客户端发送的数据中...");
            this.inputStream =new CustomObjectInputStream (clientSocket.getInputStream());

            this.clientData= (ClinetData) inputStream.readObject();
        }catch (IOException e){
            e.printStackTrace();
        } catch (ClassNotFoundException e){
            e.printStackTrace();
        }
    }

}